import { getObjType } from '../utils/util';
import { isRealNull, isRealNum, valueIsError } from './validate';
import { genarate, update ,parse_date_code} from './format';
import server from '../controllers/server';
import luckysheetConfigsetting from '../controllers/luckysheetConfigsetting';
import Store from '../store/index'
import method from './method';


import { getSheetIndex } from '../methods/get';

function changeDataVerification(r,c,v){
    // 只用把数据验证中的checked改对就行了
    const dataVerification = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].dataVerification
    for(let key in dataVerification){
        if(`${r}_${c}` == key){
            const obj = dataVerification[key]
            if(obj.type == 'radio'){
                if(Array.isArray( obj.value[0])){
                    let valueIndexArr = [-1,-1]
                    valueIndexArr[0] = obj.value.findIndex(arr=>arr.findIndex((val,index)=>{
                        if(val == v){
                            valueIndexArr[1] = index
                            return true    
                        }
                    })!=-1)
                    if(v === ','){
                        obj.checked = obj.checked.map(arr=>arr.map(()=>false))
                        return
                    }
                    if(valueIndexArr[0] < 0 && valueIndexArr[1] < 0){
                        return true
                    }else{
                        obj.checked = obj.checked.map(arr=>arr.map(()=>false))
                        obj.checked[valueIndexArr[0]][valueIndexArr[1]] = true
                    }
                }else{
                    // 老版本
                    const valueIndex = obj.value.findIndex(item=>item == v)
                    if(valueIndex < 0){
                        return true
                    }else{
                        obj.checked = obj.checked.map(b=>false)
                        obj.checked[valueIndex] = true
                    }
                }
                
            }else if(obj.type == 'check_boxs'){
                arrV = v.split(',')
                // 拍平后查找
                const errValArr = arrV.filter(val=>!obj.value.flat().includes(val))
                if(errValArr.length != 0 && v != ','){
                    return true
                }else if(v == ',' ){
                    // obj.checked = obj.checked.map(arr=>arr.map(()=>false))
                    // 兼容老版本
                    if(Array.isArray(obj.checked[0])){
                        obj.checked = obj.checked.map(arr=>arr.map(()=>false))
                    }else{
                        obj.checked = obj.checked.map(bol=>false)
                    }
                }else{
                    // obj.checked = obj.checked.map((arr,rowIndex)=>arr.map((val,index)=>{
                    //     return arrV.includes(obj.value[rowIndex][index])
                    // }))
                    // 兼容老版本
                    if(!Array.isArray(obj.checked[0])){
                        obj.checked = obj.checked.map((arr,rowIndex)=>arrV.includes(obj.value[rowIndex]))
                    }else{
                        obj.checked = obj.checked.map((arr,rowIndex)=>arr.map((val,index)=>{
                            return arrV.includes(obj.value[rowIndex][index])
                        }))
                    }
                }  
            }
        }
    }
}

//Set cell value
function setcellvalue(r, c, d, v) {
    if(d == null){
        d = Store.flowdata;
    }
    // 若采用深拷贝，初始化时的单元格属性丢失
    // let cell = $.extend(true, {}, d[r][c]);
    let cell = d[r][c];

    let vupdate;

    if(getObjType(v) == "object"){
        if(cell == null){
            cell = v;
        }
        else{
            if(v.f != null){
                cell.f = v.f;
            }else if(cell.hasOwnProperty('f')){
                delete cell.f;
            }

            if(v.spl != null){
                cell.spl = v.spl;
            }

            if(v.ct != null){
                cell.ct = v.ct;
            }
            // 
        }


        if(getObjType(v.v) == "object"){
            vupdate = v.v.v;
        }
        else{
            vupdate = v.v;
        }
    }
    else{
        vupdate = v;
    }

    if(isRealNull(vupdate)){
        if(getObjType(cell) == "object"){
            delete cell.m;
            delete cell.v;
        }
        else{
            cell = null;
        }

        d[r][c] = cell;

        return;
    }

    // 1.为null
    // 2.数据透视表的数据，flowdata的每个数据可能为字符串，结果就是cell == v == 一个字符串或者数字数据
    if(isRealNull(cell) || (getObjType(cell) === 'string' || getObjType(cell) === 'number') && cell === v){
        cell = {};
    }

    let vupdateStr = vupdate.toString();

    // nby setCellValue后又数据验证时修改数据验证
    const isError = changeDataVerification(r,c,vupdateStr)
    if(isError){
        console.error('设置的字符不是选项之一')
        return
    }
    
    if(vupdateStr.substr(0, 1) == "'"){
        cell.m = vupdateStr.substr(1);
        cell.ct = { "fa": "@", "t": "s" };
        cell.v = vupdateStr.substr(1);
        cell.qp = 1;
    }
    else if(cell.qp == 1){
        cell.m = vupdateStr;
        cell.ct = { "fa": "@", "t": "s" };
        cell.v = vupdateStr;
    }
    else if(vupdateStr.toUpperCase() === "TRUE"){
        cell.m = "TRUE";
        cell.ct = { "fa": "General", "t": "b" };
        cell.v = true;
    }
    else if(vupdateStr.toUpperCase() === "FALSE"){
        cell.m = "FALSE";
        cell.ct = { "fa": "General", "t": "b" };
        cell.v = false;
    }
    else if(vupdateStr.substr(-1) === "%" && isRealNum(vupdateStr.substring(0, vupdateStr.length-1))){
            cell.ct = {fa: "0%", t: "n"};
            cell.v = vupdateStr.substring(0, vupdateStr.length-1) / 100;
            cell.m = vupdate;
    }
    else if(valueIsError(vupdate)){
        cell.m = vupdateStr;
        // cell.ct = { "fa": "General", "t": "e" };
        if(cell.ct!=null){
            cell.ct.t = "e";
        }
        else{
            cell.ct = { "fa": "General", "t": "e" };
        }
        cell.v = vupdate;
    }
    else{
        if(cell.f != null && isRealNum(vupdate) && !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(vupdate)){
            cell.v = parseFloat(vupdate);
            if(cell.ct==null){
                cell.ct = { "fa": "General", "t": "n" };
            }

            if(cell.v == Infinity || cell.v == -Infinity){
                cell.m = cell.v.toString();
            }
            else{
                if(cell.v.toString().indexOf("e") > -1){
                    let len;
                    if(cell.v.toString().split(".").length==1){
                        len = 0;
                    }
                    else{
                        len = cell.v.toString().split(".")[1].split("e")[0].length;
                    }
                    if(len > 5){
                        len = 5;
                    }

                    cell.m = cell.v.toExponential(len).toString();
                }
                else{
                    let v_p = Math.round(cell.v * 1000000000) / 1000000000;
                    if(cell.ct==null){
                        let mask = genarate(v_p);
                        cell.m = mask[0].toString();
                    }
                    else{
                        let mask = update(cell.ct.fa, v_p);
                        cell.m = mask.toString();
                    }

                    // cell.m = mask[0].toString();
                }
            }
        }
        else if(cell.ct != null && cell.ct.fa == "@"){
            cell.m = vupdateStr;
            cell.v = vupdate;
        }
        else if(cell.ct != null && cell.ct.fa != null && cell.ct.fa != "General"){
            if(isRealNum(vupdate)){
                vupdate = parseFloat(vupdate);
            }
            // 源码：
            // let mask = update(cell.ct.fa, vupdate);
            // nby 新增“年月”
            let mask;
            if(cell.ct != null && cell.ct.fa == "Y.m"){
                let str = parse_date_code(vupdate) 
                mask = str.y + '-' + str.m.toString().padStart(2, '0')
            }else if(cell.ct != null && cell.ct.fa == "Y.m.z"){
                let str = parse_date_code(vupdate) 
                mask = str.y + '年' + str.m.toString().padStart(2, '0') + '月'
            }
            else{
                mask = update(cell.ct.fa, vupdate);
            }
            // nby 新增“年月” END

            if(mask === vupdate){ //若原来单元格格式 应用不了 要更新的值，则获取更新值的 格式
                mask = genarate(vupdate);
                // if(cell?.ct?.t !== 'n'){
                //     cell.m = mask[0].toString();
                //     cell.ct = mask[1];
                //     cell.v = mask[2];
                // }else{
                    cell.m = mask[0].toString();
                    cell.v = mask[2];
                // }

                // zxx 设置了数字，输入了日期，则自动转换为数值(time) fb2401240005
                if(cell?.ct?.t === 'n' && mask[1].t === 'd'){
                    cell.m = mask[2]
                }

                // 之前的源码
                /* cell.m = mask[0].toString();
                cell.ct = mask[1];
                cell.v = mask[2]; */
            }
            else{
                cell.m = mask.toString();
                cell.v = vupdate;
            }
        }
        // 加密
        else if(cell.ct != null && cell.ct.en === 'encry'){
            cell.m = '****'
        }
        else{
            if(isRealNum(vupdate) && !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(vupdate)){

                if(typeof vupdate === "string"){
                    let flag = vupdate.split("").every(ele=>ele == "0" || ele == ".");
                    if(flag){
                        vupdate = parseFloat(vupdate);
                    }
                }
                cell.v = vupdate;   /* 备注：如果使用parseFloat，1.1111111111111111会转换为1.1111111111111112 ? */
                cell.ct = { "fa": "General", "t": "n" };
                if(cell.v == Infinity || cell.v == -Infinity){
                    cell.m = cell.v.toString();
                }
                else{
                    let mask = genarate(cell.v);

                    cell.m = mask[0].toString();
                }
            }
            else{
                let mask = genarate(vupdate);

                cell.m = mask[0].toString();
                cell.ct = mask[1];
                cell.v = mask[2];
            }
        }
    }

    if(!server.allowUpdate && !luckysheetConfigsetting.pointEdit){
        if(cell.ct != null && /^(w|W)((0?)|(0\.0+))$/.test(cell.ct.fa) == false && cell.ct.t == "n" && cell.v != null && parseInt(cell.v).toString().length > 4){
            let autoFormatw = luckysheetConfigsetting.autoFormatw.toString().toUpperCase();
            let accuracy = luckysheetConfigsetting.accuracy;

            let sfmt = setAccuracy(autoFormatw, accuracy);

            if(sfmt != "General") {
                cell.ct.fa = sfmt;
                cell.m = update(sfmt, cell.v);
            }
        }
    }

    // nby hook updatedCellValue
    // if(Store.flowdata[r] && cell?.f){
    //     triggerHook('formulaCellUpdated',r,c,cell,false)
    // }

    d[r][c] = cell;

}
function triggerHook(hookName,r,c,cell,isRefresh,order){
    // nby 触发hook  cellUpdated
    const oldCellData = Store.flowdata[r][c]
    const curCellData = $.extend({},oldCellData)
    curCellData.v = cell.v
    curCellData.m = cell.m
    method.createHookFunction(hookName, r, c, curCellData, isRefresh,order);
}


//new runze 根据亿万格式autoFormatw和精确度accuracy 转换成 w/w0/w0.00 or 0/0.0格式
function setAccuracy(autoFormatw, accuracy) {
    let acc = "0.";
    let fmt;

    if(autoFormatw == "TRUE"){
        if(accuracy == undefined){
            return "w";
        }
        else{
            let alength = parseInt(accuracy);

            if(alength == 0){
                return "w0";
            }
            else{
                acc = "w0.";

                for(let i = 0; i < alength; i++){
                    acc += "0";
                }

                fmt = acc;
            }
        }
    }
    else{
        if(accuracy == undefined){
            return "General";
        }
        else{
            let alength = parseInt(accuracy);

            if(alength == 0){
                return "0";
            }
            else{
                for(let i = 0; i < alength; i++){
                    acc += "0";
                }

                fmt = acc;
            }

        }
    }

    return fmt.toString();
}

export {
    setcellvalue,
    setAccuracy,
}
